package com.lin.springframework;

import com.lin.app.service.UserService;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 自动代理创建器的Bean后置处理器
 * 实现AOP的BeanPostProcessor （spring内置提供的，
 *  spring框架当中我们如果要实现aop，需要有@EnableAspectJAutoPorxy注解，
 *  在这个注解当中，是通过@Import(AspectJAotoPorxyRegistrar.class导入的bean的后置处理器)）
 */
@Component
public class AutoProxyCreatorBeanPostProcessor implements BeanPostProcessor, SmartInstantiationAwareBeanPostProcessor {

    // 缓存已经创建好的aop的bean
    private final Map<String, Object> earlyBeanReferences = new ConcurrentHashMap<>(16);

    // 初始化后
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 如果没有提前创建，就在初始化后创建代理对象
        if (!earlyBeanReferences.containsKey(beanName)) {
            return createPorxy(bean, beanName);
        }
        // 如果已经提前创建过，就直接返回
        return bean;
    }

    // 循环依赖中调用，解决循环依赖的bean属性 和 容器中的bean不一致的问题
    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) {
        earlyBeanReferences.put(beanName, bean);
        return createPorxy(bean, beanName);
    }

    // 创建代理对象
    public Object createPorxy(Object bean, String beanName) {
        // 创建动态代理
        // 匹配切点表达式 ----> aspectj 能力
        // 如果是UserService，就创建动态代理
        if (bean instanceof UserService) {
            // 创建jdk动态代理
            JdkDynimcProxy jdkDynimcProxy = new JdkDynimcProxy(bean);
            // 返回代理对象
            return jdkDynimcProxy.getProxy();
        }

        System.out.println("初始化后扩展...");
        //BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
        // 没有实现aop，就返回原始bean对象
        return bean;
    }
}
